/* eslint-disable react/no-array-index-key */
import React, { forwardRef } from 'react';
import { Popconfirm, Divider, Form } from 'antd';
import cls from 'classnames';
import BrowsableInput from '../BrowsableInput';
import Icon from '../Icon';
import styles from './index.less';

const noop = () => {};
export const MODE = {
    EDITING: 'editing',
    BROWSING: 'browsing'
};
const defaultMode = MODE.EDITING;
const MutableFormItem = (
    {
        form,
        initMode = defaultMode,
        fieldDecoratorId,
        fieldDecoratorOptions = {},
        disabled,
        onConfirm = noop,
        onModeChange = noop,
        onRemove = noop,
        deleteWhenEmpty = true,
        prefix,
        suffix,
        className,
        ...rest
    },
    ref
) => {
    const { getFieldDecorator, validateFields, setFieldsValue, getFieldValue } = form;
    const { initialValue } = fieldDecoratorOptions;
    const [lastValue, setLastValue] = React.useState(initialValue);
    const [mode, setMode] = React.useState(initMode);
    const isBrowsing = React.useMemo(() => mode === MODE.BROWSING, [mode]);
    const modeChangeRef = React.useRef();
    modeChangeRef.current = onModeChange;
    const toggleMode = React.useCallback(() => {
        const nextMode = isBrowsing ? MODE.EDITING : MODE.BROWSING;
        setMode(nextMode);
        modeChangeRef.current(nextMode);
    }, [setMode, onModeChange, isBrowsing]);

    const handleConfirm = React.useCallback(() => {
        validateFields([fieldDecoratorId], async err => {
            if (err) {
                return;
            }
            try {
                const val = getFieldValue(fieldDecoratorId);

                setLastValue(val);
                await onConfirm(val);
                toggleMode();
            } catch (error) {
                console.error(error);
            }
        });
    }, [onConfirm, toggleMode]);

    const handleCancel = React.useCallback(() => {
        if (deleteWhenEmpty && !lastValue) {
            onRemove();
            return;
        }
        setFieldsValue({ [fieldDecoratorId]: lastValue });
        toggleMode();
    }, [toggleMode, setFieldsValue, deleteWhenEmpty, onRemove, lastValue]);

    const renderButtons = React.useCallback(() => {
        if (disabled) {
            return null;
        }
        const confirm = <Icon title="确定" type="confirm_o" onClick={handleConfirm} />;
        const cancel = <Icon title="取消" type="cancel_o" onClick={handleCancel} />;
        const edit = <Icon title="编辑" type="listfunction_edit_icon_default" onClick={toggleMode} />;
        const del = (
            <Popconfirm title="确定是否删除?" onConfirm={onRemove}>
                <Icon title="删除" type="DeleteIcon" />
            </Popconfirm>
        );
        const children = isBrowsing ? [edit, del] : [cancel, confirm];
        return (
            <div className={cls(styles.flex, styles.button)}>
                {children.map((btn, index) => (
                    <React.Fragment key={index}>
                        {index !== 0 && <Divider type="vertical" style={{ margin: '0 10px' }}></Divider>}
                        {btn}
                    </React.Fragment>
                ))}
            </div>
        );
    }, [isBrowsing, handleConfirm, handleCancel, toggleMode, onRemove]);

    return (
        <div className={cls(styles.flex, styles.root, className)} {...rest}>
            <Form.Item style={{ marginBottom: 0, flex: 1 }}>
                <div className={cls(styles.flex, styles.root)}>
                    {prefix}
                    {getFieldDecorator(
                        fieldDecoratorId,
                        fieldDecoratorOptions
                    )(
                        <BrowsableInput
                            className={styles.input}
                            ref={ref}
                            style={{ flex: 1 }}
                            browsing={isBrowsing}
                            autoComplete="off"
                        />
                    )}
                    {renderButtons()}
                    {suffix}
                </div>
            </Form.Item>
        </div>
    );
};
export default forwardRef(MutableFormItem);
